using System.Windows.Media.Animation;
using System.Windows.Media.Media3D;

namespace Sinacor.Infra.UI.Controls.SmartClient
{
	public abstract class ViewStateBase
	{
        private FlowPanel _owner;

		protected FlowPanel Owner 
        {
            get { return this._owner; }
            private set { this._owner = value; } 
        }

		internal void SetOwner(FlowPanel owner)
		{
			Owner = owner;
		}

		public void SelectElement(int index)
		{
			Storyboard sb = null;
			for (int leftItem = 0; leftItem < index; leftItem++)
			{
				sb = Owner.PrepareTemplateStoryboard(leftItem);
				PrepareStoryboard(sb, GetPreviousMotion(leftItem));
				Owner.AnimateElement(sb);
			}

			sb = Owner.PrepareTemplateStoryboard(index);
			PrepareStoryboard(sb, GetSelectionMotion(index));
			Owner.AnimateElement(sb);

			for (int rightItem = index + 1; rightItem < Owner.VisibleChildrenCount; rightItem++)
			{
				sb = Owner.PrepareTemplateStoryboard(rightItem);
				PrepareStoryboard(sb, GetNextMotion(rightItem));
				Owner.AnimateElement(sb);
			}
		}

		private void PrepareStoryboard(Storyboard sb, Motion motion)
		{
			AxisAngleRotation3D rotation = (sb.Children[0] as Rotation3DAnimation).To as AxisAngleRotation3D;
			DoubleAnimation xAnim = sb.Children[1] as DoubleAnimation;
			DoubleAnimation yAnim = sb.Children[2] as DoubleAnimation;
			DoubleAnimation zAnim = sb.Children[3] as DoubleAnimation;

			rotation.Angle = motion.Angle;
			rotation.Axis = motion.Axis;
			xAnim.To = motion.X;
			yAnim.To = motion.Y;
			zAnim.To = motion.Z;
		}

		protected abstract Motion GetPreviousMotion(int index);
		protected abstract Motion GetSelectionMotion(int index);
		protected abstract Motion GetNextMotion(int index);
	}
}